<%
' +----------------------------------------------------------------------
' | POPASP [ ASP MVC ]
' +----------------------------------------------------------------------
' | Copyright (c) 2016 http://popasp.com All rights reserved.
' +----------------------------------------------------------------------
' | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
' +----------------------------------------------------------------------
' | Author: popasp <1737025626@qq.com>
' +----------------------------------------------------------------------
Class POPASP_TEMPLATE_COMPILER
    ' The left delimiter used for the template tags.
    '	用于Simtpl_Compiler类
    ' @var string
    private left_delimiter

    ' The right delimiter used for the template tags.
    '	用于Simtpl_Compiler类
    ' @var string
    private right_delimiter
	
	' 在模板文件中 tpl_vars 采用什么变量名称
	private tpl_var_name
	
	
	private template,compiler
	
	private apt_prefix
	
	Private reg
	
	private lbl_index,lbl_first,lbl_last,lbl_index_prev,lbl_index_next,lbl_rownum,lbl_total
	
	Public Sub [Set] ( attr,value )	
		execute attr & " = """ & value & """"
	end sub
	
	Public Function compile( byRef context )
		compile = replace_front( context )
		
		'替换{$POP.version} 为 POP_MVC.Version
		compile = replace_complex_output_var(compile,false,"\$POP\.version","$POP.version","""" & POP_MVC.Version & """")	
		
		'替换{$POP.template} 为 template
		compile = replace_complex_output_var(compile,false,"\$POP\.template","$POP.template","""" & template & """")
		
		'替换{$POP.compiler} 为 compiler
		compile = replace_complex_output_var(compile,false,"\$POP\.compiler","$POP.compiler","""" & compiler & """")
		
		'替换{$POP.ldelim} 为 left_delimiter
		compile = replace_complex_output_var(compile,false,"\$POP\.ldelim","$POP.ldelim","""" & left_delimiter & """")	
		
		'替换{$POP.rdelim} 为 POP_MVC.Version
		compile = replace_complex_output_var(compile,false,"\$POP\.rdelim","$POP.rdelim","""" & right_delimiter & """")	
		
		'替换{$POP.config.arg} 为 配置变量
		compile = replace_complex_output_var(compile,false,"\$POP\.config(\.\w+)+","$POP.config","")
		
		'替换{$POP.const.arg} 为 系统常量
		compile = replace_complex_output_var(compile,false,"\$POP\.const(\.\w+)","$POP.const","")
		
		'替换{$POP.get} 为 Request.QueryString
		compile = replace_complex_output_var(compile,false,"\$POP\.get","$POP.get","Request.QueryString")	

		'替换{$POP.get.arg} 为 Request.QueryString("arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.get(\.\w+)+","$POP.get","Request.QueryString")		
		
		'替换{$POP.form} 为 Request.Form
		compile = replace_complex_output_var(compile,false,"\$POP\.form","$POP.form","Request.Form")	

		'替换{$POP.form.arg} 为 Request.Form("arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.form(\.\w+)+","$POP.form","Request.Form")
		
		'替换{$POP.server.arg} 为 Request.ServerVariables("arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.server\.(\w+)+","$POP.server","Request.ServerVariables")		
		
		'替换{$POP.session.arg} 为 session("arg")，未考虑缓存周期的影响
		compile = replace_complex_output_var(compile,false,"\$POP\.session(\.\w+)+","$POP.session","session")	
		
		'替换{$POP.cookie.arg} 为 Request.Cookies("arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.cookie(\.\w+)+","$POP.cookie","Request.Cookies")			
		
		'替换{$POP.apt.arg} 为 Application.Contents("arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.apt(\.\w+)+","$POP.apt","Application.Contents")
		
		'替换{$POP.memory.arg} 为 Application.Contents("前缀+arg")
		compile = replace_complex_output_var(compile,false,"\$POP\.memory(\.\w+)+","$POP.memory","Application.Contents")


		compile = compile_if(compile)
		
		compile = replace_single_output_var(compile)
		
		compile = compile_for(compile)
		
		compile = compile_foreach(compile)
		
		compile = compile_switch(compile)
		
		compile = compile_func_output(compile)
		
		compile = compile_run_func(compile)		
		
		compile = compile_default_output(compile)
		
		'替换{$var.key} {$var.key1.key2}为tpl("var")("key")	tpl("var")("key1")("key2")
		compile = replace_complex_output_var(compile,true,"\$(\w+\.?)+","$",tpl_var_name)
		compile = replace_after( compile )
	End Function
	
	private Function replace_complex_line_vars ( context )
		'替换{$POP.version} 为 POP_MVC.Version
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.version","$POP.version","""" & POP_MVC.Version & """")
		
		'替换{$POP.template} 为 POP_MVC.template
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.template","$POP.template","""" & template & """")

		'替换{$POP.compiler} 为 POP_MVC.compiler
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.compiler","$POP.compiler","""" & compiler & """")		
		
		'替换{$POP.ldelim} 为 left_delimiter
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.ldelim","$POP.ldelim","""" & left_delimiter & """")	
		
		'替换{$POP.rdelim} 为 right_delimiter
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.rdelim","$POP.rdelim","""" & right_delimiter & """")	
		
		'替换{$POP.config} 为 配置变量
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.config(\.\w+)+","$POP.config","")	

		'替换{$POP.const} 为 系统常量
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.const(\.\w+)","$POP.const","")	
		

	
		'替换{$POP.get.arg} 为 Request.QueryString("arg")
		replace_complex_line_vars = replace_complex_line_var(context,false,"\$POP\.get(\.\w+)+","$POP.get","Request.QueryString")	

		'替换{$POP.get} 为 Request.QueryString
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.get","$POP.get","Request.QueryString")		
				
		'替换{$POP.form.item} 为 Request.Form(item)
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.form(\.\w+)+","$POP.form","Request.Form")
		
		'替换{$POP.form} 为 Request.form
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.form","$POP.form","Request.Form")		
				
		'替换{$POP.server} 为 Request.ServerVariables
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.server\.(\w+)","$POP.server","Request.ServerVariables")
		
		'替换{$POP.server} 为 Request.ServerVariables
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.server","$POP.server","Request.ServerVariables")		
		
		'替换{$POP.session} 为 session
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.session(\.\w+)+","$POP.session","session")		
				
		'替换{$POP.cookie} 为 Request.Cookies
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.cookie(\.\w+)+","$POP.cookie","Request.Cookies")
		
		'替换{$POP.apt} 为 Application.Contents
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.apt(\.\w+)+","$POP.apt","Application.Contents")	
		
		'替换{$POP.server} 为 Request.ServerVariables
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.apt","$POP.apt","Application.Contents")		
		
		'替换{$POP.memory} 为 Application.Contents，未考虑缓存周期的影响
		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,false,"\$POP\.memory(\.\w+)+","$POP.memory","Application.Contents")		

		replace_complex_line_vars = replace_complex_line_var(replace_complex_line_vars,true,"\$(\w+\.?)+","$",tpl_var_name)	
	end Function	
	
	
	'替换单个要打印的变量{$var}  {$var.key} {$var.key1.key2}  {var}  {tpl("arg")}等等
	private Function replace_single_output_var ( context )
		'替换{$var} 为 <%  If tpl.Exists("var") Then Response.Write(tpl("var")) End If %>
		context = POP_MVC.String.reg_replace(context,"<" & "% " & " If " & tpl_var_name & ".Exists(""$1"") Then Response.Write " & tpl_var_name & "(""$1"") End If" & " %" & ">" , left_delimiter & "\s*\$(\w+)\s*"	& right_delimiter , "gim")
		
		'替换{var} 为 <%  If tpl.Exists("var") Then Response.Write(tpl("var")) End If %>
		context = POP_MVC.String.reg_replace(context,"<" & "% " & "Response.Write " & "$1" & " %" & ">" ,left_delimiter & "\s*(\w+)\s*"	& right_delimiter,"gim" )
		
		'替换{ tpl("arg") } 为 <%  If tpl.Exists("var") Then Response.Write(tpl("var")) End If %>
		context = POP_MVC.String.reg_replace(context,"<" & "% " & "Response.Write " & "$1" & " %" & ">" ,left_delimiter & "\s*(" & tpl_var_name & "\("".+""\.?\)+)\s*"	& right_delimiter , "gim")
		
		replace_single_output_var = context
	end Function
	
	
	'替换{for $i = 0 to 10 step 1} ... {/for}
	private Function compile_foreach ( context )
		dim str,i,matches,for_key,for_item,for_var,arr

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*foreach\s+(.+)\s+in\s+(.+)\s*" & right_delimiter,"gim")
		
		' {for each key as item in var} 替换为 For Each key In var : If isObject( var("key") ) Then Set item = var("key") Else item = var("key")
		for i = 0 to matches.count-1
			arr = split( LCase(matches(i).subMatches(0))," as " )
			for_key = trim( arr(0) )
			if ubound(arr) > 0 then
				for_item = trim( arr(1) )
				for_item = replace_complex_line_vars( for_item )
			else
				for_item = ""
			end if
			for_var = replace_complex_line_vars( matches(i).subMatches(1) )
			str = get_lbl(lbl_total) & " = 0" & vbCrLf
			str = str & "If isArray(" & for_var & ")" & " Then " & vbCrLf
			str = str & get_lbl(lbl_total) & " = UBound(" & for_var & ") + 1" & vbCrLf
			str = str & "Else" & vbCrLf
			str = str & "Select Case typename( " & for_var & " )" & vbCrLf
			str = str & "  Case ""Dictionary"",""Files"",""IVariantDictionary"",""IRequestDictionary"" : " & get_lbl(lbl_total) & " = " & for_var & ".Count" & vbCrLf
			str = str & "  Case ""Recordset"" : " & get_lbl(lbl_total) & " = " & for_var & ".RecordCount" & vbCrLf
			str = str & "  Case ""ISessionObject"" : " & get_lbl(lbl_total) & " = " & for_var & ".Contents.Count" & vbCrLf
			str = str & "End Select" & vbCrLf
			str = str & "End If" & vbCrLf
			str = str & get_lbl(lbl_rownum) & " = 0" & vbCrLf		
			str = str & "If " & get_lbl(lbl_total) & " >0 Then" & vbCrLf			
			if for_item <> "" then
				str = str & "For Each " & for_key & " In " & for_var & " : If isObject( " & for_var & "(" & for_key & ") ) Then Set " & for_item & " = " & for_var & "(" & for_key & ") Else " &  for_item & " = " & for_var & "(" & for_key & ")" & vbCrLf	
			else
				str = str & "For Each " & for_key & " In " & for_var & vbCrLf			
			end if
			str = str & "If " & get_lbl(lbl_rownum) & " = 0 Then " &  get_lbl(lbl_first) & " = True Else " &  get_lbl(lbl_first) & " = False" & vbCrLf			
			str = str & get_lbl(lbl_rownum) & " = " &  get_lbl(lbl_rownum) & " + 1" & vbCrLf
			str = str & get_lbl(lbl_index) & " = " &  get_lbl(lbl_rownum) & " - 1" & vbCrLf
			str = str & "If " & get_lbl(lbl_total) & " <> 0 AND " & get_lbl(lbl_total) & " = " & get_lbl(lbl_rownum) & " Then " &  get_lbl(lbl_last) & " = True"  & " Else " &  get_lbl(lbl_last) & " = False " & vbCrLf
			str = str & "If " & get_lbl(lbl_total) & " < " & get_lbl(lbl_rownum) & " Then " &  get_lbl(lbl_total) & " = "  & get_lbl(lbl_rownum) & vbCrLf
			str = "<" & "% " & vbCrLf & str & "%" & ">"
			context = Replace(context,matches(i),str )
		next	
		
		compile_foreach = context
		
		'替换{/foreach} 为 <%  End If %>
		compile_foreach = POP_MVC.String.reg_replace(compile_foreach,"<" & "% " & " Next " & vbCrLf & "End If " & " %" & ">",left_delimiter & "\s*/foreach\s*"	& right_delimiter,"gim")		
		
		set matches = nothing
	end Function
	
	'默认值输出
	private Function compile_default_output ( context )
		dim str,i,matches,arg,val

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*(.+)\s*\|\s*default\s*=\s*(.+)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			arg = replace_complex_line_vars(matches(i).subMatches(0))
			val = replace_complex_line_vars(matches(i).subMatches(1))
			str = "If isArray( " & arg & " ) Then" & vbCrLf
			str = str & "  if ubound(" & arg & ") <0 then Response.Write " & val & " End If" & vbCrLf
			str = str & "Else " & vbCrLf
			str = str & "  " & tpl_var_name & "(""__default_output__"") = " & val & vbCrLf
			str = str & "  Select Case Typename(" & arg & ")" & vbCrLf
			str = str & "    case ""String"",""IStringList"" : If " & arg & " <> """" Then " & tpl_var_name & "(""__default_output__"") = " & arg & vbCrLf
			str = str & "    case ""Dictionary"",""Files"",""IVariantDictionary"" : If " & arg & ".Count <> 0 Then Set "  & tpl_var_name & "(""__default_output__"") = " & arg & vbCrLf
			str = str & "    case ""ISessionObject"" : If " & arg & ".Contents.Count <> 0 Then Set " & tpl_var_name & "(""__default_output__"") = " & arg & vbCrLf
			str = str & "    case ""Empty"",""Null"",""Unknown"",""Nothing"",""Error"" : " & tpl_var_name & "(""__default_output__"") = " & val & vbCrLf
			str = str & "    case else :" & tpl_var_name & "(""__default_output__"") = " & arg & vbCrLf
			str = str & "  End Select " & vbCrLf
			str = str & "End If " & vbCrLf
			str = str & "Response.Write " &  tpl_var_name & "(""__default_output__"")"  & vbCrLf
			str = "<" & "%" & vbCrLf & str & vbCrLf & "%" & ">"
			
			context = Replace(context,matches(i),str )
		next		
		
		compile_default_output = context
		set matches = nothing
	end Function
	
	'执行函数但不输出
	private Function compile_run_func ( context )
		dim str,i,matches,condition,str_true,str_false
		
		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*~(.+?)\?(.+?):(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			condition = replace_complex_line_vars(matches(i).subMatches(0))
			str_true = replace_complex_line_vars(matches(i).subMatches(1))
			str_false = replace_complex_line_vars(matches(i).subMatches(2))
			str = "If ( " & condition & " ) Then" & vbCrLf
			str = str & str_true & vbCrLf
			str = str & "Else" & vbCrLf
			str = str & str_false & vbCrLf
			str = str & "End If" & vbCrLf
			str = "<" & "%" & vbCrLf & str & "%" & ">"
			context = Replace(context,matches(i),str )
		next

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*~(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = replace_complex_line_vars(matches(i).subMatches(0))
			str = "<" & "% " &  str & " %" & ">"
			context = Replace(context,matches(i),str )
		next		
		
		compile_run_func = context
		set matches = nothing
	end Function
	
	
	'执行函数并输出
	private Function compile_func_output ( context )
		dim str,i,matches,condition,str_true,str_false
		
		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*:(.+?)\?(.+?):(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			condition = replace_complex_line_vars(matches(i).subMatches(0))
			str_true = replace_complex_line_vars(matches(i).subMatches(1))
			str_false = replace_complex_line_vars(matches(i).subMatches(2))
			str = "If ( " & condition & " ) Then" & vbCrLf
			str = str & "Response.Write (" & str_true & ")" & vbCrLf
			str = str & "Else" & vbCrLf
			str = str & "Response.Write (" & str_false & ")" & vbCrLf
			str = str & "End If" & vbCrLf
			str = "<" & "%" & vbCrLf & str & "%" & ">"
			context = Replace(context,matches(i),str )
		next

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*:(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = replace_complex_line_vars(matches(i).subMatches(0))
			str = "<" & "%" &  " Response.Write (" & str & ") " & "%" & ">"
			context = Replace(context,matches(i),str )
		next		
		
		compile_func_output = context
		set matches = nothing
	end Function
	
	'switch条件选择
	private Function compile_switch ( context )
		dim str,i,matches
		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*switch\s+(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = replace_complex_line_vars(matches(i).subMatches(0))
			str = "<" & "% " &  " Select Case " & str & " %" & ">"
			context = Replace(context,matches(i),str )
		next

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*case\s+(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = replace_complex_line_vars(matches(i).subMatches(0))
			str = "<" & "% " &  " Case " & str & " : %" & ">"
			context = Replace(context,matches(i),str )
		next	

		'替换{/default}  为 <%  Case Else: %>
		context = POP_MVC.String.reg_replace(context,"<" & "% " & " Case Else: " & " %" & ">",left_delimiter & "\s*/default\s*"	& right_delimiter,"gim" )		
		
		'替换{/switch} 为 <%  End Select %>
		compile_switch = POP_MVC.String.reg_replace(context,"<" & "% " & " End Select " & " %" & ">",left_delimiter & "\s*/switch\s*"	& right_delimiter,"gim" )
		set matches = nothing
	end Function
	
	
	'替换{for $i = 0 to 10 step 1} ... {/for}
	private Function compile_for ( context )
		dim str,i,matches,for_start,for_end,for_counter,for_step,arr
		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*for\s+(.+?)=\s*(.+?)\s+to\s+(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			for_counter = trim(matches(i).subMatches(0))
			for_start = matches(i).subMatches(1)
			arr = split( LCase(matches(i).subMatches(2))," step " )
			for_end = trim( arr(0) )
			if ubound(arr) > 0 then
				for_step = trim( arr(1) )
				if for_step = "" or for_step = "0" then
					for_step = "1"
				end if
			else
				for_step = "1"
			end if
			for_end = replace_complex_line_vars( for_end )
			str = get_lbl(lbl_total) & " = Int((" & for_end & " - " & for_start & ")/" & for_step & ") + 1" & vbCrLf
			str = str & "If " &  get_lbl(lbl_total) & " < 0 Then" & vbCrLf
			str = str & get_lbl(lbl_total) & " = 0" & vbCrLf
			str = str & "Else" & vbCrLf
			str = str & get_lbl(lbl_index_prev) & " = -1 " & vbCrLf			
			str = str & get_lbl(lbl_rownum) & " = 0" & vbCrLf			
			str = "<" & "%" & vbCrLf & str & "For " & for_counter & " = " & for_start & " To " & for_end  & " Step " & for_step & vbCrLf 
			str = str & get_lbl(lbl_index) & " = " & for_counter & vbCrLf
			str = str & get_lbl(lbl_rownum) & " = " & get_lbl(lbl_rownum) & " + 1 " & vbCrLf
			str = str & "If " & for_counter & " = " & for_start & " Then " & get_lbl(lbl_first) & " = True Else " & get_lbl(lbl_first) & " = False"  & " : " & get_lbl(lbl_index_prev) & " = " & for_counter & " - " & for_step & vbCrLf
			str = str & "If " & get_lbl(lbl_rownum) & " = " & get_lbl(lbl_total) & " Then " & get_lbl(lbl_last) & " = True Else " & get_lbl(lbl_last) & " = False : " & get_lbl(lbl_index_next) & " =  " & for_counter & " + " & for_step & vbCrLf
			str = str & "If " & get_lbl(lbl_total) & " < " & get_lbl(lbl_rownum) & " Then " & get_lbl(lbl_total) & " = " & get_lbl(lbl_rownum) & vbCrLf
			str = str & "%" & ">"
			context = Replace(context,matches(i),str )
		next		
		
		compile_for = context
		
		'替换{/for} ，替换{/if} 为 <%  End If %>
		compile_for = POP_MVC.String.reg_replace(compile_for,"<" & "% " & "Next : End If" & " %" & ">",left_delimiter & "\s*/for\s*"	& right_delimiter,"gim" )		
		
		set matches = nothing
	end Function
	
	private function get_lbl(lbl)
		get_lbl = tpl_var_name & "(""" & lbl & """)"
	end function
	
	
	'替换{if arg="..."} ... {/if}
	private Function compile_if ( context )
		dim str,i,matches

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*(else)?if\s+(.+?)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = matches(i).subMatches(1)
			str = replace_complex_line_vars(str)
			str = "<" & "% " & matches(i).subMatches(0) & "If " & str & " Then %" & ">"
			context = Replace(context,matches(i),str )
		next
		
		set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\s*(else)?if\((.+?)\)\s*" & right_delimiter,"gim")
		
		for i = 0 to matches.count-1
			str = matches(i).subMatches(1)
			str = replace_complex_line_vars(str)
			str = "<" & "% " & matches(i).subMatches(0) & "If (" & str & ") Then %" & ">"
			context = Replace(context,matches(i),str )
		next		
		
		compile_if = context
		
		'替换{else} 为 <% Else %>
		compile_if = POP_MVC.String.reg_replace(compile_if,"<" & "% " & " Else " & " %" & ">",left_delimiter & "\s*/else\s*"	& right_delimiter, "gim" )		
		
		'替换{/if} 为 <%  End If %>
		compile_if = POP_MVC.String.reg_replace(compile_if,"<" & "% " & " End If " & " %" & ">" ,left_delimiter & "\s*/if\s*"	& right_delimiter , "gim"  )		
		
		set matches = nothing
	end Function
	
	
	'替换单个变量$var $var.key $var.key1.key2 及系统变量 等等
	private Function replace_complex_line_var ( context,ignoreCase,pattern,find_str,replace_str )
		dim str,i,matches,len_find: len_find = len(find_str)
		reg.Global = true : reg.IgnoreCase = ignoreCase : reg.MultiLine = true	
		reg.Pattern = pattern
		set matches = reg.execute(context)

		for i = 0 to matches.count-1
			str = mid( matches(i), len_find + 1 ,len(matches(i)) - len_find )			
			pos = inStr(str,".")
			if inStr(str,".")>0 then
				if pos = 1 then
					str = mid(str,2)
				end if
				
				
				if find_str = "$POP.memory" then	'将数据存到内存中时，带有前缀，且只支持$POP.memory.arg一维形式
					str = apt_prefix & str
				end if			
				
				str = Replace(str,".",""")(""" )							
				
				if str<> "" AND find_str <> "$POP.const" then
					str = "(""" & str & """)"
				end if
				
				if find_str = "$POP.config" then	'配置文件中的变量
					Execute "str = POP_MVC.config" & str
					if typename(str) = "String" then
						str = """" & CStr(str) & """"
					end if
				end if
				
				if find_str = "$POP.const" then	'配置文件中的变量
					Execute "str = " & str
					str = """" & str & """"
				end if
			elseif replace_str = tpl_var_name then			
				str = "(""" & str & """)" 
			end if
			
			'比如将tpl("item")("__key__")("__item__") 替换为 tpl("item")(key)(item)
			str = POP_MVC.String.reg_replace( str,"$1" , """__(\w+)__""","ig" )
			str = replace_str & str
			context = Replace(context,matches(i),str )
		next		
		replace_complex_line_var = context
		set matches = nothing
	end Function
	
	'替换单个要打印的变量{$var}  {$var.key} {$var.key1.key2} 及系统变量 等等
	private Function replace_complex_output_var ( context,ignoreCase,pattern,find_str,replace_str )
		dim str,i,len_left,len_right,len_find,pos,matches,temp
		temp = find_str
		
		len_left = len( left_delimiter ) : len_right = len( right_delimiter ) : len_find = len(find_str)		

		set matches = POP_MVC.String.reg_exec(context,left_delimiter & pattern & right_delimiter,"gim")

		for i = 0 to matches.count-1			
			str = mid( matches(i), len_left + len_find + 1 ,len(matches(i))- len_left - len_right - len_find )
			pos = inStr(str,".")
			if inStr(str,".")>0 then
				if pos = 1 then
					str = mid(str,2)
				end if
				if find_str = "$POP.memory" then	'将数据存到内存中时，带有前缀，且只支持$POP.memory.arg一维形式
					str = apt_prefix & str
				end if				
				
				str = Replace(str,".",""")(""" )				
				
				if str<> "" AND find_str <> "$POP.const" then
					str = "(""" & str & """)"
				end if
				
				if find_str = "$POP.config" then	'配置文件中的变量
					Execute "str = POP_MVC.config" & str
					if typename(str) = "String" then
						str = """" &  str & """"
					end if
				end if	
				
				if find_str = "$POP.const" then	'配置文件中的变量
					Execute "str = " & str
					str = """" & CStr(str) & """"
				end if
			end if
			
			'比如将tpl("item")("__key__")("__item__") 替换为 tpl("item")(key)(item)
			str = POP_MVC.String.reg_replace( str,"$1" , """__(\w+)__""","ig" )
			
			str = "<" & "% Response.Write " & replace_str & str & " %" & ">"
			context = Replace(context,matches(i),str )
		next		
		replace_complex_output_var = context
		set matches = nothing
	end Function	
	
	' 放在后面的替换,包括输出单个变量等
	Private function replace_after( context )
		dim matches,str,arr,item,config,i
		
		'替换{$session.key} 为 <% Response.Write session("key") %>
		context = POP_MVC.String.reg_replace(context,"<" & "% " & "Response.Write session(""$1"")" & " %" & ">" ,left_delimiter & "\$session\.(\w+)" & right_delimiter,"gim")	
		
		'替换{$var.key1.key2} 为 <%  Response.Write tpl("abc")("key1")("key2") %>
		if ( POP_MVC.String.reg_test(context,left_delimiter & "\$((\w+)(?:\.(\w+))+)"	& right_delimiter,"gim") ) Then
			set matches = POP_MVC.String.reg_exec(context,left_delimiter & "\$((\w+)(?:\.(\w+))+)"	& right_delimiter,"gim")
				for i = 0 to matches.count-1
				str = matches(i).SubMatches(0)
				arr = split(str,".")
				str = tpl_var_name
				for each item in arr
					str = str & "(""" & item & """)"				
				next
				context = replace(context, matches(i)  , "<" & "% Response.Write " & str & " %" & ">" )
			next
		End If
		
		
		'替换TMPL_PARSE_STRING
		set config = POP_MVC.getConfig("TMPL_PARSE_STRING")
		if Not isEmpty(config) Then
			for each item in config
				context = Replace(context,item,config(item) )
			next		
		End If
		
		'删除空白行
		context = POP_MVC.String.reg_replace(context,"","^\s+$","gm")

		
		replace_after = context
		set matches = nothing
	End Function  'end function replace_basic(context)
	
	
	
	'放在前面的替换,包括删除左右边界的空格
	Private function replace_front( byRef context )
		' 删除标签边界不必要的空格
		context = POP_MVC.String.reg_replace( context , left_delimiter & "$1" & right_delimiter , left_delimiter & "\s*(.*?)\s*" & right_delimiter , "gim")
		
		' 一行注释的替换 {//注释内容 }
		context = POP_MVC.String.reg_replace( context , "", left_delimiter & "//.*?" & right_delimiter , "gim")
		
		' 多注释的替换 {/*注释内容*/}
		context = POP_MVC.String.reg_replace( context , "" , left_delimiter & "/\*[\s\S]*?\*/" & right_delimiter , "gim")
		
		replace_front =  context
	End Function  'end function replace_front(context)		
	
  
	Public Sub init ( byRef l_d,byRef r_d ,byRef var_name)		
		left_delimiter	= l_d
		right_delimiter = r_d
		tpl_var_name	= var_name
		
		lbl_index = C_("TMPL_COMPILE_INDEX")
		
		lbl_rownum = C_("TMPL_COMPILE_ROWNUM")
		
		lbl_first = C_("TMPL_COMPILE_FIRST")
		
		lbl_last = C_("TMPL_COMPILE_LAST")
		
		lbl_index_prev = C_("TMPL_COMPILE_INDEX_PREV")
		
		lbl_index_next = C_("TMPL_COMPILE_INDEX_NEXT")

		lbl_total = C_("TMPL_COMPILE_TOTAL")
	End Sub
	
	
	Private Sub Class_Terminate		
		set tpl_vars = nothing
		set fso = nothing
		set data_cache_vars = nothing
	End Sub  
	
	Private Sub Class_Initialize
		' The left delimiter used for the template tags.
		left_delimiter  =  "{"

		' The right delimiter used for the template tags.
		right_delimiter =  "}"
		
		' 在模板文件中 tpl_vars 采用什么变量名称
		tpl_var_name = "tpl"
		
		set reg = POP_MVC.reg		
		
		lbl_index = "_index"
		
		lbl_rownum = "_rownum"
		
		lbl_first = "_first"
		
		lbl_last = "_last"
		
		lbl_index_prev = "_index_prev"
		
		lbl_index_next = "_index_next"

		lbl_total = "_total"
		
		apt_prefix = C_("TMPL_MEM_PREFIX")
	End Sub	
  
End Class
%>